package com.xsh.web.weixin;


import com.xsh.config.WxConfig;
import com.xsh.util.MessageUtil;
import com.xsh.util.XMLMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import weixin.popular.api.MenuAPI;
import weixin.popular.bean.BaseResult;
import weixin.popular.bean.message.EventMessage;
import weixin.popular.bean.xmlmessage.XMLImageMessage;
import weixin.popular.bean.xmlmessage.XMLTextMessage;
import weixin.popular.support.ExpireKey;
import weixin.popular.support.TokenManager;
import weixin.popular.support.expirekey.DefaultExpireKey;
import weixin.popular.util.SignatureUtil;
import weixin.popular.util.XMLConverUtil;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lixing
 * @date 2021/5/24 18:49
 */
@Slf4j
@Controller
@RequestMapping("/wxService")
public class WxServiceController {

    @Autowired
    private WxConfig wxConfig;
    @Autowired
    WxMsgController msgController;

    //过滤重复通知
    private static ExpireKey expireKey = new DefaultExpireKey();

    //微信服务器验证
    @RequestMapping(value = "/sign", method = RequestMethod.GET)
    @ResponseBody
    public void doGet(@RequestParam Map<String, String> param, HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        ServletOutputStream outputStream = response.getOutputStream();

        String signature = param.get("signature");
        String echoser = param.get("echostr");
        String timestamp = param.get("timestamp");
        String nonce = param.get("nonce");

        if (StringUtils.isEmpty(signature) || StringUtils.isEmpty(timestamp)) {
            outputStreamWrite(outputStream, "request faild");
            return;
        }
        //对称加密 本地
        String token = wxConfig.getToken();
        /**
         * 将token、timestamp、nonce三个参数进行字典序排序
         *
         * 将三个参数字符串拼接成一个字符串进行sha1加密
         *
         * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
         */
        if (!signature.equals(SignatureUtil.generateEventMessageSignature(token, timestamp, nonce))) {
            outputStreamWrite(outputStream, "签名错误");
            System.out.println("签名错误");
            return;
        }

        if (echoser != null) {
            outputStreamWrite(outputStream, echoser);
            return;
        }


    }

    //接收微信服务端消息
    @RequestMapping(value = "/sign", method = RequestMethod.POST)
    @ResponseBody
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        ServletOutputStream outputStream = response.getOutputStream();
        if (inputStream != null) {

            //转换XML
            EventMessage eventMessage = XMLConverUtil.convertToObject(EventMessage.class, inputStream);
            String fromUserName = eventMessage.getFromUserName();//用户openid
            String toUserName = eventMessage.getToUserName();//公众号原始id
            String msgType = eventMessage.getMsgType();      //消息类型(事件、消息)

//            log.info("eventMessage:{}", ToStringBuilder.reflectionToString(eventMessage));
            System.out.println("eventMessage_is:"+ ToStringBuilder.reflectionToString(eventMessage));
            String key = eventMessage.getFromUserName() + "_" + eventMessage.getToUserName() + "_" + eventMessage.getMsgId() + "_" + eventMessage.getCreateTime();
            if (expireKey.exists(key)) {
                System.err.println("重复通知");
                return;
            } else {
                expireKey.add(key);
            }

            if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
                String event = eventMessage.getEvent();
                System.out.println("这是一个事件");
            } else {
                if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { // 文本消息
                    //测试模板消息
                    String msg = eventMessage.getContent();
                    if (msg.equals("模板消息")) {
                        HashMap<String, String> map = new HashMap<>();
                        map.put("openId",fromUserName);
                        msgController.list(map);
                        return;
                    }
                    XMLTextMessage xmlTextMessage = new XMLTextMessage(fromUserName,toUserName,"测试文本消息");
//                    xmlTextMessage.outputStreamWrite(outputStream);
                    XMLMessage xmlMessage = new XMLMessage(fromUserName, toUserName, "测试");
                    xmlMessage.outputStreamWrite(outputStream);
                    return;
                }
                if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
                    XMLImageMessage xmlTextMessage = new XMLImageMessage(eventMessage.getFromUserName(), eventMessage.getToUserName(), eventMessage.getMediaId());
                    xmlTextMessage.outputStreamWrite(outputStream);
                    return;
                }


                //其他消息
                XMLTextMessage xmlTextMessage = new XMLTextMessage(eventMessage.getFromUserName(), eventMessage.getToUserName(), "<a href=\"http://lxing-it.cn/profile/my\">完善个人信息</a>");
                xmlTextMessage.outputStreamWrite(outputStream);
                return;


                //回复
            /*XMLTextMessage xmlTextMessage = new XMLTextMessage(eventMessage.getFromUserName(), eventMessage.getToUserName(), "<a href=\"http://3ztnk2.natappfree.cc/profile/my\">完善个人信息</a>");
            if (null != xmlTextMessage) {
                xmlTextMessage.outputStreamWrite(outputStream);
            }*/

            }
        }
    }


    @RequestMapping("/createMenu")
    @ResponseBody
    public BaseResult createMenu() {
        String menu = "{\n" +
                "    \"button\": [\n" +
                "        {\n" +
                "            \"type\": \"click\", \n" +
                "            \"name\": \"今日歌曲\", \n" +
                "            \"key\": \"V1001_TODAY_MUSIC\"\n" +
                "        }, \n" +
                "        {\n" +
                "            \"name\": \"菜单\", \n" +
                "            \"sub_button\": [\n" +
                "                {\n" +
                "                    \"type\": \"view\", \n" +
                "                    \"name\": \"搜索\", \n" +
                "                    \"url\": \"http://www.soso.com/\"\n" +
                "                }, \n" +
                "                {\n" +
                "                    \"type\": \"click\", \n" +
                "                    \"name\": \"赞一下我们\", \n" +
                "                    \"key\": \"V1001_GOOD\"\n" +
                "                }\n" +
                "            ]\n" +
                "        }\n" +
                "    ], \n" +
                "    \"matchrule\": {\n" +
                "        \"tag_id\": \"2\", \n" +
                "        \"sex\": \"1\", \n" +
                "        \"country\": \"中国\", \n" +
                "        \"province\": \"广东\", \n" +
                "        \"city\": \"广州\", \n" +
                "        \"client_platform_type\": \"2\", \n" +
                "        \"language\": \"zh_CN\"\n" +
                "    }\n" +
                "}";

        String menu2 = "{\n" +
                "    \"button\": [\n" +
                "        {\n" +
                "            \"name\": \"扫码\", \n" +
                "            \"sub_button\": [\n" +
                "                {\n" +
                "                    \"type\": \"scancode_waitmsg\", \n" +
                "                    \"name\": \"扫码带提示\", \n" +
                "                    \"key\": \"rselfmenu_0_0\", \n" +
                "                    \"sub_button\": [ ]\n" +
                "                }, \n" +
                "                {\n" +
                "                    \"type\": \"scancode_push\", \n" +
                "                    \"name\": \"扫码推事件\", \n" +
                "                    \"key\": \"rselfmenu_0_1\", \n" +
                "                    \"sub_button\": [ ]\n" +
                "                }\n" +
                "            ]\n" +
                "        }, \n" +
                "        {\n" +
                "            \"name\": \"发图\", \n" +
                "            \"sub_button\": [\n" +
                "                {\n" +
                "                    \"type\": \"pic_sysphoto\", \n" +
                "                    \"name\": \"系统拍照发图\", \n" +
                "                    \"key\": \"rselfmenu_1_0\", \n" +
                "                   \"sub_button\": [ ]\n" +
                "                 }, \n" +
                "                {\n" +
                "                    \"type\": \"pic_photo_or_album\", \n" +
                "                    \"name\": \"拍照或者相册发图\", \n" +
                "                    \"key\": \"rselfmenu_1_1\", \n" +
                "                    \"sub_button\": [ ]\n" +
                "                }, \n" +
                "                {\n" +
                "                    \"type\": \"pic_weixin\", \n" +
                "                    \"name\": \"微信相册发图\", \n" +
                "                    \"key\": \"rselfmenu_1_2\", \n" +
                "                    \"sub_button\": [ ]\n" +
                "                }\n" +
                "            ]\n" +
                "        }, \n" +
                "        {\n" +
                "            \"name\": \"发送位置\", \n" +
                "            \"type\": \"location_select\", \n" +
                "            \"key\": \"rselfmenu_2_0\"\n" +
                "        }\n" +
                "    ]\n" +
                "}";
        //String acctoken = "45_xONFKeiUOIo8QfkLcIM_hquHnsLJyBqII2mA5oODMJffqrL00qGgOHnj4sPUHoR4BvXd-styEisVIB8RluirAe69t3pWO0d4QOZjiJAz8wAyBN9F3n9tBBH5Iyufy3jG9mlijbsXLw_H2JfpLFBfADAPJF";
        BaseResult menuCreate = MenuAPI.menuCreate(TokenManager.getDefaultToken(), menu2);

        return menuCreate;
    }

    private boolean outputStreamWrite(ServletOutputStream outputStream, String s) {

        try {
            outputStream.write(s.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /*
    public String get() {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
        String result = restTemplate.getForObject(url + "&appid="+wxConfig.getAppID()+"&secret="+wxConfig.getAppsecret(), String.class);
        JSONObject jsonObject = JSON.parseObject(result);
        String objectString = jsonObject.getString("access_token");
        return objectString;
    }


    public void test() {
        String rootUrl = null;
        //1. 简单Get请求
        String result = restTemplate.getForObject(rootUrl + "get1?para=my", String.class);
        System.out.println("简单Get请求:" + result);

        //2. 简单带路径变量参数Get请求
        result = restTemplate.getForObject(rootUrl + "get2/{1}", String.class, 239);
        System.out.println("简单带路径变量参数Get请求:" + result);

        //3. 返回对象Get请求（注意需包含compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'）
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(rootUrl + "get3/339", String.class);
        System.out.println("返回:" + responseEntity);
        System.out.println("返回对象Get请求:" + responseEntity.getBody());

        //4. 设置header的Get请求
        HttpHeaders headers = new HttpHeaders();
        headers.add("token", "123");
        ResponseEntity<String> response = restTemplate.exchange(rootUrl + "get4", HttpMethod.GET, new HttpEntity<String>(headers), String.class);
        System.out.println("设置header的Get请求:" + response.getBody());

        //5. Post对象
        Test1 test1 = new Test1();
        test1.name = "buter";
        test1.sex = 1;
        result = restTemplate.postForObject(rootUrl + "post1", test1, String.class);
        System.out.println("Post对象:" + result);

        //6. 带header的Post数据请求
        response = restTemplate.postForEntity(rootUrl + "post2", new HttpEntity<String>(test1, headers), String.class);
        System.out.println("带header的Post数据请求:" + response.getBody());

        //7. 带header的Put数据请求
        //无返回值
        restTemplate.put(rootUrl + "put1", new HttpEntity<Test1>(test1, headers));
        //带返回值
        response = restTemplate.exchange(rootUrl + "put1", HttpMethod.PUT, new HttpEntity<Test1>(test1, headers), String.class);
        System.out.println("带header的Put数据请求:" + response.getBody());

        //8. del请求
        //无返回值
        restTemplate.delete(rootUrl + "del1/{1}", 332);
        //带返回值
        response = restTemplate.exchange(rootUrl + "del1/332", HttpMethod.DELETE, null, String.class);
        System.out.println("del数据请求:" + response.getBody());
    }*/
}
